/*
 * Tema: 4 SBC-uri cu mem. partajata intre adresele 
 * 0xff-0x3ff.
 */

module board4;

  reg [11:0] addr1, addr2, addr3, addr4;
  wire BR, BBZ, SACK;
  wire bg12, bg23, bg34;

  KMAG k1 (addr1, BR, 'b1, bg12, BBZ, SACK);
  KMAG k2 (addr2, BR, bg12, bg23, BBZ, SACK);
  KMAG k3 (addr3, BR, bg23, bg34, BBZ, SACK);
  KMAG k4 (addr4, BR, bg34,/*nimic !*/, BBZ, SACK);

  initial begin
    addr1 = 0;
    addr2 = 0;
    addr3 = 0;
    addr4 = 0;
    #1;
//    addr = 10;
    addr1 = 'h100;
    #2;
    addr2 = 'h110;
    #10;
  end

endmodule


/*
* Am considerat:
* sack activ pe 1
* br activ pe 1
* bg
* bgIn, bgOut : bus grant in/out (daisy chaining)
*/
module KMAG (addr, br, bgIn, bgOut, bb, sack);

  inout br, bb, sack;
  input bgIn;
  output bgOut;

  wire br, bb, bgIn, sack;
  reg bgOut;
  input addr;
  wire [11:0]addr;

  reg req, res, busy;
  assign br = req;
  assign sack = res;
  assign bb = busy;

  initial begin
    res = 'bz;
    req = 'bz;
    bgOut = 1;
    busy = 'bz;
  end

  task startRequest;
    begin
      $display("%m: sack = %b", sack);
      if (sack == 1) begin  //astept sack = 0
        $display("%m: astept sa pot face rezervarea...");
        while (sack == 1)  #1@(sack); 
      end
      req = 1; //activez linia br
      $display("%m: rezevare facuta");
      $display("%m: bgIn = %b", bgIn);
      if (bgIn == 0) begin //astept bgIn = 1
        $display("%m: astept bus grant...");
        while (bgIn == 0)  #1@(bgIn);
        $display("%m: ok");
      end
      req = 'bz;
      res = 1;
      $display("%m: busy = %b", bb);
      if (bb == 1) begin
        $display("%m: astept sa se termine operatia in curs");
        while(bb == 1) #1@(bb);
        $display("%m: ok");
      end
      #1;
      busy = 1;
      res = 'bz;
      $display("%m: acces in afara initiat");
      #5;
      $display("%m: terminat acces in afara");
      busy = 'bz;
    end
  endtask

  always @(addr) begin
    if (addr < 'hff) 
      begin //acces local
        $display("%m: acces local la adresa: %h", addr);
      end 
    else 
      begin
        $display("%m: acces in afara la adresa: %h", addr);
        startRequest;
      end
  end
endmodule

